package com.haide.channel.pro.util;


import com.haide.channel.pro.constant.CharacterDict;
import com.haide.channel.pro.constant.HttpDict;
import com.haide.channel.pro.constant.NumberDict;
import com.haide.channel.pro.enums.ErrorCodeEnum;
import com.haide.channel.pro.exception.HttpException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * http操作工具类
 * <p>
 * 1.
 * </p>
 *
 * @author : wukong
 * @version : 1.0.0
 * @date : 2018/6/27
 */
@Slf4j
@Component
public class HttpUtil {
    /**
     * 请求超时时间设置
     */
    private static RequestConfig requestConfig = RequestConfig.custom()
            .setSocketTimeout(NumberDict.SIXTY * NumberDict.MILLISECOND)
            .setConnectTimeout(NumberDict.SIXTY * NumberDict.MILLISECOND)
            .setConnectionRequestTimeout(NumberDict.SIXTY * NumberDict.MILLISECOND)
            .build();
    /**
     * http连接池
     */
    @Autowired
    private HttpConnectionManager httpConnectionManager;


    /**
     * post请求
     *
     * @param url     url地址
     * @param param   内容
     * @param charset 字符集
     * @return String
     */
    public String post(String url, Map<String, String> param, String charset) {
        String returnStr;
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            List<NameValuePair> pairList = mapConvertPair(param);
            httpPost.setEntity(new UrlEncodedFormEntity(pairList, charset));
            returnStr = getResult(httpPost, charset);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    /**
     * post请求
     *
     * @param url       url地址
     * @param param     请求参数
     * @param headParam 头部参数
     * @param charset   字符集
     * @return String
     */
    public String post(String url, Map<String, String> param, Map<String, String> headParam, String charset) {
        String returnStr;
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            setHead(headParam, httpPost);
            List<NameValuePair> pairList = mapConvertPair(param);
            httpPost.setEntity(new UrlEncodedFormEntity(pairList, charset));
            returnStr = getResult(httpPost, charset);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    public String post(String url, byte[] content, String charset, Map<String, String> headParam) {
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            this.setHead(headParam, httpPost);
            httpPost.setEntity(new ByteArrayEntity(content));
            String returnStr = this.getResult(httpPost, charset);
            return returnStr;
        } catch (Exception var7) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, var7);
        }
    }

    /**
     * post请求
     *
     * @param url     url地址
     * @param content 内容
     * @return String
     */
    public String post(String url, String content) {
        String returnStr;
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            setHead(null, httpPost);
            httpPost.setEntity(new StringEntity(content, CharacterDict.UTF_8));
            returnStr = getResult(httpPost, CharacterDict.UTF_8);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    /**
     * post请求
     *
     * @param url       url地址
     * @param content   内容
     * @param charset   字符集
     * @param headParam 头部参数
     * @return String
     */
    public String post(String url, String content, String charset, Map<String, String> headParam) {
        String returnStr;
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            setHead(headParam, httpPost);
            httpPost.setEntity(new StringEntity(content, charset));
            returnStr = getResult(httpPost, charset);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    /**
     * post请求
     *
     * @param url     url地址
     * @param content 内容
     * @param format  格式
     * @param charset 字符集
     * @return String
     */
    public String post(String url, String content, String format, String charset) {
        String returnStr;
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            httpPost.setEntity(new StringEntity(content, charset));
            httpPost.setHeader(HttpDict.HEAD_CONTENT, format);
            returnStr = getResult(httpPost, charset);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    /**
     * get请求
     *
     * @param url url地址
     * @return String
     */
    public String get(String url) {
        String returnStr;
        try {
            HttpGet httpGet = new HttpGet(url);
            httpGet.setConfig(requestConfig);
            setHead(null, httpGet);
            httpGet.setURI(new URI(url));
            returnStr = getResult(httpGet, CharacterDict.UTF_8);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    public String get(String url, String body) {
        String returnStr;
        try {
            HttpGetWithEntity oHttpGet = new HttpGetWithEntity(url);
            HttpEntity httpEntity = new StringEntity(body, ContentType.APPLICATION_JSON);
            oHttpGet.setConfig(requestConfig);
            oHttpGet.setEntity(httpEntity);
            returnStr = getResult(oHttpGet, CharacterDict.UTF_8);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    /**
     * get请求
     *
     * @param url       url地址
     * @param charset   字符集
     * @param headParam 头部参数
     * @return String
     */
    public String get(String url, String charset, Map<String, String> headParam) {
        String returnStr;
        try {
            HttpGet httpGet = new HttpGet(url);
            httpGet.setConfig(requestConfig);
            setHead(headParam, httpGet);
            httpGet.setURI(new URI(url));
            returnStr = getResult(httpGet, charset);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    /**
     * get请求
     *
     * @param url       url地址
     * @param param     内容
     * @param charset   字符集
     * @param headParam 头部参数
     * @return String
     */
    public String get(String url, Map<String, String> param, String charset, Map<String, String> headParam) {
        String returnStr;
        try {
            HttpGet httpGet = new HttpGet(url);
            httpGet.setConfig(requestConfig);
            setHead(headParam, httpGet);
            List<NameValuePair> pairList = mapConvertPair(param);
            String str = URLEncodedUtils.format(pairList, charset);
            httpGet.setURI(new URI(url.concat("?").concat(str)));
            returnStr = getResult(httpGet, charset);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    /**
     * get请求
     *
     * @param url     url地址
     * @param param   内容
     * @param charset 字符集
     * @return String
     */
    public String get(String url, Map<String, String> param, String charset) {
        String returnStr;
        try {
            HttpGet httpGet = new HttpGet(url);
            httpGet.setConfig(requestConfig);
            List<NameValuePair> pairList = mapConvertPair(param);
            String str = URLEncodedUtils.format(pairList, charset);
            httpGet.setURI(new URI(url.concat("?").concat(str)));
            returnStr = getResult(httpGet, charset);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    /**
     * delete请求
     *
     * @param url       url地址
     * @param param     内容
     * @param charset   字符集
     * @param headParam 头部参数
     * @return String
     */
    public String delete(String url, Map<String, String> param, String charset, Map<String, String> headParam) {
        String returnStr;
        try {
            HttpDelete httpDelete = new HttpDelete(url);
            httpDelete.setConfig(requestConfig);
            setHead(headParam, httpDelete);
            List<NameValuePair> pairList = mapConvertPair(param);
            String str = URLEncodedUtils.format(pairList, charset);
            httpDelete.setURI(new URI(url.concat("?").concat(str)));
            returnStr = getResult(httpDelete, charset);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    /**
     * delete请求
     *
     * @param url     url地址
     * @param param   内容
     * @param charset 字符集
     * @return String
     */
    public String delete(String url, Map<String, String> param, String charset) {
        String returnStr;
        try {
            HttpDelete httpDelete = new HttpDelete(url);
            httpDelete.setConfig(requestConfig);
            List<NameValuePair> pairList = mapConvertPair(param);
            String str = URLEncodedUtils.format(pairList, charset);
            httpDelete.setURI(new URI(url.concat("?").concat(str)));
            returnStr = getResult(httpDelete, charset);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    /**
     * put请求
     *
     * @param url       url地址
     * @param param     内容
     * @param charset   字符集
     * @param headParam 头部参数
     * @return String
     */
    public String put(String url, Map<String, String> param, String charset, Map<String, String> headParam) {
        String returnStr;
        try {
            HttpPut httpPut = new HttpPut(url);
            httpPut.setConfig(requestConfig);
            setHead(headParam, httpPut);
            List<NameValuePair> pairList = mapConvertPair(param);
            String str = URLEncodedUtils.format(pairList, charset);
            httpPut.setURI(new URI(url.concat("?").concat(str)));
            returnStr = getResult(httpPut, charset);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    /**
     * put请求
     *
     * @param url     url地址
     * @param param   内容
     * @param charset 字符集
     * @return String
     */
    public String put(String url, Map<String, String> param, String charset) {
        String returnStr;
        try {
            HttpPut httpPut = new HttpPut(url);
            httpPut.setConfig(requestConfig);
            List<NameValuePair> pairList = mapConvertPair(param);
            String str = URLEncodedUtils.format(pairList, charset);
            httpPut.setURI(new URI(url.concat("?").concat(str)));
            returnStr = getResult(httpPut, charset);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    /**
     * post请求
     *
     * @param url       url地址
     * @param content   内容
     * @param format    格式
     * @param charset   字符集
     * @param headParam 头部参数
     * @return String
     */
    public String put(String url, String content, String format, String charset, Map<String, String> headParam) {
        String returnStr;
        try {
            HttpPut httpPut = new HttpPut(url);
            httpPut.setConfig(requestConfig);
            setHead(headParam, httpPut);
            httpPut.setEntity(new StringEntity(content, charset));
            httpPut.setHeader(HttpDict.HEAD_CONTENT, format);
            returnStr = getResult(httpPut, charset);
        } catch (Exception e) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, e);
        }
        return returnStr;
    }

    /**
     * post请求
     *
     * @param url     url地址
     * @param content 内容
     * @param format  格式
     * @param charset 字符集
     * @return String
     */
    public String put(String url, String content, String format, String charset) {
        String returnStr;
        try {
            HttpPut httpPut = new HttpPut(url);
            httpPut.setConfig(requestConfig);
            httpPut.setEntity(new StringEntity(content, charset));
            httpPut.setHeader(HttpDict.HEAD_CONTENT, format);
            returnStr = getResult(httpPut, charset);
        } catch (Exception e) {
            throw new RuntimeException();
        }
        return returnStr;
    }

    /**
     * post请求
     * 发送文件
     *
     * @param url
     * @param builder
     * @param format
     * @param charset
     * @param headParam
     * @return
     */
    public String post(String url, MultipartEntityBuilder builder, String format, String charset, Map<String, String> headParam) {
        try {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            this.setHead(headParam, httpPost);
            httpPost.setEntity(builder.build());
            httpPost.setHeader("Content-Type", format);
            String returnStr = this.getResult(httpPost, charset);
            return returnStr;
        } catch (Exception var7) {
            throw new HttpException(ErrorCodeEnum.ERROR_CODE_100004, var7);
        }
    }

    /**
     * 设置请求头
     *
     * @param headParam 头部
     * @param request   HttpRequestBase
     */
    private void setHead(Map<String, String> headParam, HttpRequestBase request) {
        if (headParam != null) {
            for (String item : headParam.keySet()) {
                request.addHeader(item, headParam.get(item));
            }
        }
    }

    /**
     * map转换pair
     *
     * @param param Map<String, String>
     * @return List<NameValuePair>
     */
    private List<NameValuePair> mapConvertPair(Map<String, String> param) {
        List<NameValuePair> pairList = new ArrayList<>();
        if (param != null) {
            for (String item : param.keySet()) {
                pairList.add(new BasicNameValuePair(item, param.get(item)));
            }
        }
        return pairList;
    }

    /**
     * 获取响应
     *
     * @param request HttpRequestBase
     * @param charset String
     * @return String
     */
    private String getResult(HttpRequestBase request, String charset) throws IOException {
        CloseableHttpClient httpClient = httpConnectionManager.getHttpClient();
        String returnStr;
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            log.info("http请求回复对象：{}", response);
            HttpEntity entity = response.getEntity();
            if (entity == null) {
                return null;
            }
            returnStr = EntityUtils.toString(response.getEntity(), charset);
        }
        return returnStr;
    }


}
